<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>html5 canvas demo (star shower) -- zswang 2010</title>
		<style type="text/css">
			#canvas{
				background-color:Black;
			}

		</style>
	</head>
	<body>
		<canvas id="canvas" width="700" height="500"></canvas>
		<script>
			var canvas = document.getElementById("canvas"), context = canvas.getContext("2d");
			
			var starShower = {
				count: 100,
				items: {},
				/**
				 * 五角星路径
				 */
				paths: [[0.512, 0.0483], [0.8104, 0.9758], [0.0241, 0.4032], [1, 0.4032], [0.2137, 0.9758]],
				next: function() {
					var item, i;
					for (i = 0; i < this.count; i++) {
						item = this.items[i];
						if (!item) this.items[i] = item = { 
							kick: 10 * Math.random(), // 变化增量 
							time: 50 * Math.random(), // 到达下一个状态的时间
							point: [canvas.width * Math.random(), canvas.height * Math.random()], // 当前位置
							state: ["hide", "show", "flash", "move"][parseInt(4 * Math.random())] // 当前状态
						};
						switch (item.state) {
							case "show": // 正常显示
								if (item.kick >= item.time) {
									item.kick = 0;
									item.time = 30;
									item.state = "flash";
								}
								break;
							case "flash":
								if (item.kick >= item.time) {
									item.kick = 0;
									item.time = 0;
									item.state = "move";
								}
								break;
							case "move":
								if (item.point[1] <= canvas.height) {
									item.point[1] += item.kick;
								} else {
									item.kick = 0;
									item.time = 0;
									item.state = "hide";
								}
								break;
							default: // "hide" 隐藏状态
								if (!item.time) {
									item.time = 100 * Math.random();
									item.kick = 0;
								} else if (item.kick >= item.time) {
									item.point = [canvas.width * Math.random(), canvas.height * Math.random()];
									item.state = "show";
									item.time = 100;
									item.kick = 0;
								}
								break;
						} 
						item.kick++; // 变化值增加
					}
					this.draw();
				},
				/**
				 * 星星大小
				 */
				size: 30,
				pathItem: function(item) {
					if (!item) return;
					var p = this.paths[0], i;
					context.moveTo(item.point[0] + p[0] * this.size, item.point[1] + p[1] * this.size);
					for (i = 1; i < this.paths.length; i++) {
						p = this.paths[i];
						context.lineTo(item.point[0] + p[0] * this.size, item.point[1] + p[1] * this.size);
					}
				},
				drawItems: function(checker, fillStyle) {
					var item, i;
					context.beginPath();
					for (i = 0; i < this.count; i++) {
						item = this.items[i];
						if (checker(item)) {
							//document.title = i;
							this.pathItem(item);
						}
					}
					context.fill();
				},
				draw: function() {
					context.clearRect(0, 0, canvas.width, canvas.height);
					context.save();
					context.fillStyle = "Red";
					this.drawItems(function(item) { return item.state == "show" });

					context.fillStyle = "#0cc";
					this.drawItems(function(item) { return item.state == "flash" && item.kick % 2 == 0 });

					context.fillStyle = "#0ee";
					context.shadowColor = "#0dd";
					this.drawItems(function(item) { return item.state == "flash" && item.kick % 2 != 0 });

					context.fillStyle = "#f0f";
					context.shadowColor = "#c0c";
					this.drawItems(function(item) { return item.state == "move" });

					context.restore();
				},
				play: function() {
					if (this.timer) return;
					self = this;
					this.timer = setInterval(function() {
						self.next();
					}, 100);
				},
				stop: function() {
					clearInterval(this.timer);
					this.timer = 0;
				}
			};
			starShower.play();
		</script>
	</body>
</html>